﻿use async_trait::async_trait;
use rand::{seq::SliceRandom, Rng};
use std::time::Instant;
use yansi::Paint;
use crate::args::AppConfig;
use crate::io::{csleep, dprint, newline, print};
use crate::modules::Module;
use crate::data::APK_PACKAGES_LIST;

 

pub struct Apt;
#[async_trait(?Send)]
impl Module for Apt {
    fn name(&self) -> &'static str {
        "apt"
    }

    fn signature(&self) -> String {
        "sudo apt install <package>".to_string()
    }

    async fn run(&self, appconfig: &AppConfig) {
        let mut rng = rand::thread_rng();
        let num_packages = rng.gen_range(3..6);

        let chosen: Vec<_> = APK_PACKAGES_LIST  
            .choose_multiple(&mut rng, num_packages)
            .copied()
            .collect();

        let now = Instant::now();

        // 模拟前置信息
        println!("正在读取软件包列表... 完成");
        csleep(400).await;
        println!("正在分析软件包的依赖关系树");
        csleep(300).await;
        println!("正在读取状态信息... 完成");
        csleep(300).await;

        println!("下列【新】软件包将被安装：");
        println!("  {}", chosen.join(" "));
        println!(
            "升级了 0 个软件包，新安装了 {} 个软件包，要卸载 0 个软件包，有 0 个软件包未被升级。",
            chosen.len()
        );
        println!(
            "需要下载 {} kB 的归档。",
            rng.gen_range(900..4000)
        );
        println!(
            "解压缩后会消耗 {} kB 的额外空间。",
            rng.gen_range(2000..8000)
        );
        newline().await;

        // 模拟下载中
        for (i, pkg) in chosen.iter().enumerate() {
            let size = rng.gen_range(100..900);
            let line = format!(
                "正在获取:{:1} http://archive.ubuntu.com/ubuntu focal/main amd64 {} [ {} kB ]",
                i + 1,
                pkg,
                size
            );
            print(line).await;
            newline().await;
            csleep(rng.gen_range(300..800)).await;
            if appconfig.should_exit() {
                return;
            }
        }

        println!("已下载 {} kB，耗时 {}秒 ({:.0} kB/s)",
                 rng.gen_range(1000..4000),
                 rng.gen_range(1..2),
                 rng.gen_range(3000..7000)
        );
        newline().await;

        // 模拟安装阶段
        for pkg in chosen.iter() {
            println!("正在选中未选择的软件包 {}。", pkg);
            println!("(正在读取数据库 ... 当前共 {} 个文件和目录已安装。)", rng.gen_range(200000..300000));
            println!("准备解压 .../{}.deb  ...", pkg);
            println!("正在解压 {}...", pkg);
            csleep(rng.gen_range(300..1000)).await;
            println!("正在设置 {}...", pkg);
            newline().await;

            if appconfig.should_exit() {
                return;
            }
        }

        // 模拟触发器
        println!("正在处理用于 man-db (2.9.1-1) 的触发器 ...");
        println!("正在处理用于 libc-bin (2.31-0ubuntu9.9) 的触发器 ...");

        // 最后总结
        let elapsed = now.elapsed();
        let seconds = elapsed.as_secs_f32();
        dprint(
            format!(
                "{stage:>12} installed {} packages in {seconds:.2} secs",
                chosen.len(),
                stage = Paint::green("完成").bold(),
            ),
            0,
        )
            .await;
        newline().await;
    }
}
